/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.report.service.impl;

import com.koron.report.bean.DrillPlanAnalysis;
import com.koron.report.mapper.DrillPlanAnalysisMapper;
import com.koron.report.service.api.DrillPlanAnalysisService;
import com.koron.report.util.BusinessCode;
import com.koron.util.Constant;
import com.koron.web.org.bean.DepartmentQueryBean;
import com.koron.web.org.bean.DepartmentTreeBean;
import com.koron.web.org.service.OrgService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.swan.bean.MessageBean;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Service
public class DrillPlanAnalysisServiceImpl implements DrillPlanAnalysisService {
    private final static  Logger logger= LoggerFactory.getLogger(DrillPlanAnalysisServiceImpl.class);

    /**
     * 组织树关系缓存
     */
    public static HashMap<String, List<String>> departmentBranch = new HashMap<>();

    /**
     * 应急演练统计
     * @param orgCode
     * @param departmentCode
     * @return
     */
    @Override
    public MessageBean<?> analysisDrillPlan(String orgCode, String departmentCode) {
        MessageBean<List> msg = MessageBean.create(BusinessCode.SUCCESS.getCode(), BusinessCode.SUCCESS.getDescription(), List.class);
        try(SessionFactory factory=new SessionFactory()) {

            if (StringUtils.isEmpty(orgCode) || StringUtils.isEmpty(departmentCode)) {
                msg.setCode(BusinessCode.EMPTY_PARAM_REQUIRED.getCode());
                msg.setDescription(BusinessCode.EMPTY_PARAM_REQUIRED.getDescription());
                return msg;
            }
            DepartmentQueryBean query = new DepartmentQueryBean();
            query.setOrgCode(orgCode);
            query.setDepartmentCode(departmentCode);
            //查询下一层级部门即可
            query.setRecursive(0);
            //存当前组织 与下层组织对应关系
            OrgService orgService = new OrgService();
            MessageBean<Map> departments = orgService.getDepartments(factory, query);
            if (departments.getCode()!= Constant.MESSAGE_INT_SUCCESS) {
                return departments;
            }
            //当前部门层级
            List<DepartmentTreeBean> depList = (List<DepartmentTreeBean>) departments.getData().get("list");
            query.setRecursive(1);
            MessageBean<Map> depTrees = orgService.getDepartments(factory, query);
            if (depTrees.getCode() != Constant.MESSAGE_INT_SUCCESS) {
                return depTrees;
            }
            List<DepartmentTreeBean> downLevels = (List<DepartmentTreeBean>) depTrees.getData().get("list");
            MessageBean<Map> depMsg = checkAndUpdateBranch(factory, depList, orgService, query);
            if (depMsg!=null) {
                return depMsg;
            }
            DrillPlanAnalysisMapper mapper = factory.getMapper(DrillPlanAnalysisMapper.class);



            //结果数据 需要与当前层级的组织code进行匹配 合并
            List<DrillPlanAnalysis> res = mapper.analysisTypeAndNum(downLevels);
            List<DrillPlanAnalysis> resList = buildRes(depList,res);
            if (CollectionUtils.isNotEmpty(res)) {
                //结果数据没有对应完整，说明树结构需要更新
                departmentBranch = new HashMap<>();
                checkAndUpdateBranch(factory,depList,orgService,query);
                //重新对结构数据封装
                List<DrillPlanAnalysis> newRes = mapper.analysisTypeAndNum(depList);
                buildRes(depList,newRes);
            }
            updateResult(resList);
            msg.setData(resList);
            return msg;
        } catch (Exception e){
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.EXCEPTION.getCode());
            msg.setDescription(BusinessCode.EXCEPTION.getDescription());
            return msg;
        }
    }

    /**
     * 更新组织树结构
     */
    private MessageBean<Map> checkAndUpdateBranch(SessionFactory factory,
                                      List<DepartmentTreeBean> depList,
                                      OrgService orgService,
                                      DepartmentQueryBean query){
        for (DepartmentTreeBean bean : depList) {
            if (departmentBranch.get(bean.getDepartmentCode())==null) {
                //树结构暂无此数据的下层数据
                query.setDepartmentCode(bean.getDepartmentCode());
                MessageBean<Map> depTrees = orgService.getDepartments(factory, query);
                if (depTrees.getCode() != Constant.MESSAGE_INT_SUCCESS) {
                    return depTrees;
                }
                List<DepartmentTreeBean> downLevels = (List<DepartmentTreeBean>) depTrees.getData().get("list");
                List<String> collect = downLevels.stream().map(DepartmentTreeBean::getDepartmentCode).collect(Collectors.toList());

                departmentBranch.put(bean.getDepartmentCode(),collect);
            }
        }
        return null;
    }

    /**
     * 构建结果数据
     */
    private List<DrillPlanAnalysis> buildRes(List<DepartmentTreeBean> depList,
                                            List<DrillPlanAnalysis> res){
        boolean notEmpty = CollectionUtils.isNotEmpty(res);
        List<DrillPlanAnalysis> resList = new ArrayList<>();
        for (DepartmentTreeBean dep : depList) {
            DrillPlanAnalysis anaBean = new DrillPlanAnalysis();
            anaBean.setDepartmentCode(dep.getDepartmentCode());
            anaBean.setDepartmentName(dep.getName());
            List<String> depCodes = departmentBranch.get(dep.getDepartmentCode());
            if (notEmpty) {
                for (int i = 0; i < res.size(); i++) {
                    if (depCodes.contains(res.get(i).getDepartmentCode())) {
                        //如果事当前层级的下层组织
                        anaBean.getTypeTotal().addAll(res.get(i).getTypeTotal());
                    }
                }
            }
            resList.add(anaBean);
        }
        return resList;
    }

    /**
     * 更新结果数据
     * @param resList
     */
    private void updateResult(List<DrillPlanAnalysis> resList){
        for (DrillPlanAnalysis bean : resList) {
            List<DrillPlanAnalysis> typeTotal = bean.getTypeTotal();
            Map<String, List<DrillPlanAnalysis>> collect = typeTotal.stream().collect(Collectors.groupingBy(DrillPlanAnalysis::getDrillType));
            List<DrillPlanAnalysis> inList = new ArrayList<>();
            AtomicInteger i = new AtomicInteger();
            for (Map.Entry<String, List<DrillPlanAnalysis>> integerListEntry : collect.entrySet()) {
                DrillPlanAnalysis be = new DrillPlanAnalysis();
                be.setDrillType(integerListEntry.getKey());
                for (DrillPlanAnalysis drillPlanAnalysis : integerListEntry.getValue()) {
                    i.addAndGet(drillPlanAnalysis.getDrillPeopleNum());
                }
                be.setDrillPeopleNum(i.get());
                i.set(0);
                inList.add(be);
            }
            bean.setTypeTotal(inList);
        }
    }
}
